home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
workbench werkzeuge
/
scherz programme
/
clicker
/
source
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
8KB
|
312 lines
/* File: main.c
* Created: 01-01-95
* Updated: 30-12-95
* Version: 1.00
* Project: Clicker
* Owner: Jeroen Vermeulen
* Requirements: KickStart V39+
* Legal: PD
* Status: Release
*/
char verstr[]="$VER: Clicker 1.0 (30.12.95) Jeroen Vermeulen",
descrp[]="Clicker 1.0 - Public Domain";
/* TODO:
* Prefs save option!
* Add note names to frequency display
* Improve sound quality (longer sample perhaps?)
*/
#include <proto/exec.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/memory.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <proto/utility.h>
#include <proto/commodities.h>
#include <proto/gadtools.h>
#include <proto/alib.h>
#include <intuition/gadgetclass.h>
#include "main.h"
#include "broker.h"
#include "prefs.h"
#include "sound.h"
#include "gui.h"
STRPTR AllocFailMsgPort = "Unable to set up message port!\n";
static STRPTR
Break_Exit = "**BREAK** -- Clicker removed\n";
/* EventLoop():
* This is where our commodity does its work. This function receives
* CX messages and acts on them, mostly by making noises.
* If anything should go wrong, errptr is directed to an error string
* and the return value is set accordingly. If all is well, this should
* be RETURN_OK.
*/
static int EventLoop(STRPTR *const errptr,
CxObj *const brokerobj,
struct MsgPort *const cxport,
struct IOAudio *const soundrequest,
struct WindowContext *const PrefsWin)
{
const ULONG waitmask = SIGBREAKF_CTRL_C | (1<<(cxport->mp_SigBit));
/* --- */
for (;;)
{
struct Message *msg;
BOOL closewin = FALSE;
const ULONG gotsig = Wait(waitmask|(PrefsWin->SigMask));
/* --- */
if (gotsig & SIGBREAKF_CTRL_C)
{
*errptr = Break_Exit;
return(RETURN_WARN);
}
while ((msg = GetMsg(cxport)))
{
CxMsg *const cxmsg = (CxMsg *)msg;
ULONG msgid = CxMsgID(cxmsg);
ULONG msgtype = CxMsgType(cxmsg);
BOOL clicknow = FALSE;
switch (msgtype)
{
case CXM_COMMAND: switch (msgid)
{
case CXCMD_DISABLE:
ActivateCxObj(brokerobj,FALSE);
break;
case CXCMD_ENABLE:
ActivateCxObj(brokerobj,TRUE);
break;
case CXCMD_KILL:
return(RETURN_OK);
case CXCMD_APPEAR:
case CXCMD_UNIQUE:
ShowWindow(errptr,PrefsWin);
break;
case CXCMD_DISAPPEAR:
closewin = TRUE;
break;
}
break;
case CXM_IEVENT:
{
struct InputEvent *const ievent =
(struct InputEvent *)CxMsgData(cxmsg);
if (!(ievent->ie_Code & IECODE_UP_PREFIX))
{
switch (ievent->ie_Class)
{
#ifndef NOCLICKMOUSE
case IECLASS_RAWMOUSE:
clicknow = ClickPrefs.ClickMouse;
break;
#endif /* NOCLICKMOUSE */
case IECLASS_RAWKEY:
clicknow = TRUE;
break;
default:
break;
}
}
}
break;
default:
break;
}
ReplyMsg(msg);
if (clicknow) KeyClick(soundrequest);
}
if (PrefsWin->Shown)
{
struct IntuiMessage *imsg;
/* --- */
while ((imsg = GT_GetIMsg(PrefsWin->Win->UserPort)))
{
const ULONG imsg_Class = imsg->Class;
const UWORD imsg_Code = imsg->Code;
struct Gadget *const g = imsg->IAddress;
/* --- */
GT_ReplyIMsg(imsg);
switch (imsg_Class)
{
case IDCMP_GADGETDOWN:
case IDCMP_GADGETUP:
case IDCMP_MOUSEMOVE:
switch (g->GadgetID)
{
case mygadget_volume:
ClickPrefs.volume = imsg_Code;
ClickPrefs.newsettings = TRUE;
break;
case mygadget_cycles:
ClickPrefs.cycles = imsg_Code;
ClickPrefs.newsettings = TRUE;
break;
case mygadget_period:
ClickPrefs.period = SliderToPeriod(imsg_Code);
ClickPrefs.newsettings = TRUE;
break;
#ifndef NOCLICKMOUSE
case mygadget_clickmouse:
ClickPrefs.ClickMouse = (g->Flags & GFLG_SELECTED);
break;
#endif /* NOCLICKMOUSE */
default:
break;
}
break;
case IDCMP_CLOSEWINDOW:
closewin = TRUE;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(PrefsWin->Win);
GT_EndRefresh(PrefsWin->Win,TRUE);
break;
default:
break;
}
}
if (closewin) HideWindow(PrefsWin);
}
}
}
/* MatchStr():
* Boolean frontend for stricmp(). Returns TRUE if the strings pointed to by
* its arguments are identical (case-insensitive comparison), or FALSE if not.
*/
static BOOL MatchStr(const STRPTR a, const STRPTR b)
{
return (BOOL)(Stricmp((UBYTE *)a,(UBYTE *)b)==0);
}
/* BoolAttr():
* Returns whether a tooltype string should be interpreted as TRUE. Defaults to
* FALSE if no string is given, but TRUE if the string is empty.
* Hopefully this behaviour allows tooltypes to be set without arguments.
*/
static BOOL BoolAttr(const UBYTE *const value)
{
UBYTE *val = (UBYTE *)value;
if (val && (!*val || MatchStr(val,"TRUE") || MatchStr(val,"YES") ||
MatchStr(val,"ON")))
return TRUE;
else return FALSE;
}
int main(LONG argc, UBYTE **argv)
{
int returnval = RETURN_FAIL;
STRPTR error = NULL;
BYTE CX_Priority = 0;
BOOL cx_popup = FALSE;
struct NewBroker *mybroker;
struct IOAudio *soundrequest;
/* There may already be another copy of Clicker running, so prefs settings are
* gathered into a temporary struct to prevent them from overwriting those of
* the active Clicker.
*/
struct SoundSettings TempPrefs;
/* --- */
soundrequest = CreateSample(&error);
if (soundrequest)
{
if ((IconBase = OpenLibrary("icon.library",36)))
{
UBYTE **ToolTypes;
/* --- */
if ((ToolTypes=ArgArrayInit(argc,argv)))
{
/* Read tooltype settings for click sound
*/
TempPrefs.period = HertzToPeriod(ArgInt(ToolTypes,"PITCH",739));
TempPrefs.volume = ArgInt(ToolTypes,"VOLUME",(ULONG)ClickPrefs.volume);
TempPrefs.cycles = ArgInt(ToolTypes,"LENGTH",(ULONG)ClickPrefs.cycles);
#ifdef NOCLICKMOUSE
TempPrefs.ClickMouse = FALSE;
#else /* NOCLICKMOUSE */
TempPrefs.ClickMouse = BoolAttr(ArgString(ToolTypes,"CLICKMOUSE","NO"));
#endif /* NOCLICKMOUSE */
cx_popup = BoolAttr(ArgString(ToolTypes,"CX_POPUP","NO"));
ArgArrayDone();
}
CloseLibrary(IconBase);
}
/* Unpleasantness happens if LENGTH is set to zero. Checking for this is
* worth the bother if you ask me.
*/
if (!TempPrefs.cycles) TempPrefs.cycles = 1;
TempPrefs.newsettings = TRUE;
mybroker = MakeBroker(&error, CX_Priority);
if (mybroker)
{
CxObj *brokerobj;
/* --- */
if ((brokerobj = SetupBroker(&error,mybroker)))
{
struct WindowContext *PrefsWin;
/* --- */
if ((PrefsWin = MakeWindow(&error,cx_popup)))
{
CopySoundPrefs(&TempPrefs,&ClickPrefs);
ActivateCxObj(brokerobj,TRUE);
returnval = EventLoop(&error, brokerobj, mybroker->nb_Port,
soundrequest, PrefsWin);
ActivateCxObj(brokerobj,FALSE);
DestroyWindow(PrefsWin);
}
DeleteCxObjAll(brokerobj);
}
KillBroker(mybroker);
}
DeleteSample(soundrequest);
}
if (error)
{
PutStr(error);
}
return(returnval);
}